﻿
using Admin.NET.Core;
using Admin.NET.Core.Service.Hub;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using IotContract.Dtos.Remotes.Request;
using IotContract.Dtos.Remotes.Response;
using IotContract.Enums;
using IotContract.Models;
using IotContract.Models.Clients;
using IotContract.Models.Jobs.F29;
using IotContract.Models.Process;
using IotContract.Models.Writes;
using IotContract.Models.Writes.F29;
using IotFun.Const;
using IotFun.Entity;
using IotFun.Models;
using IotFun.Views.EquipInfoView;
using IotFun.Views.EquipTagView;
using IotFun.Views.MainView.Dto;
using IotServerService.Services;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using NewLife.Serialization.Json;
using ProtoBuf.Grpc.Configuration;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XT.Common.Extensions;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.CgibinTagsMembersGetBlackListResponse.Types;


namespace IotFun.Services;

/// <summary>
/// Grpc对外服务
/// </summary>
[ApiDescriptionSettings(IotConst.GroupName, Order = 1)]
public class GrpcServerService : IDynamicApiController, ITransient
{

    #region 字段
    private readonly GrpcService _grpcService;
    private readonly EquipTagService _tagService;
    private readonly EquipInfoService _equipService;
    private readonly ISqlSugarClient _sqlSugarClient;
    #endregion

    #region 构造函数
    public GrpcServerService(GrpcService grpcService, EquipTagService tagService,EquipInfoService equipInfoService, ISqlSugarClient sqlSugarClient)
    {
        _grpcService = grpcService;
        _tagService = tagService;
        _equipService = equipInfoService;
        _sqlSugarClient = sqlSugarClient;
    }
    #endregion




    #region 获取数据


    /// <summary>
    /// 获取设备统计信息（包含异常）
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    [Route("groupstatistic")]
    [ApiDescriptionSettings(Name = "groupstatistic")]
    public async Task<List<GroupRunningData>> GetGroupStatistic()
    {
        var result = await _grpcService.GetGroupStatistic();
        if (result.IsSuccess)
        {
            return result.Data;
        }
        else
        {
            throw Oops.Oh(result.Msg);
        }
    }


    /// <summary>
    /// 获取调度数据
    /// </summary>
    /// <param name="command"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "ProcessData")]
    [AllowAnonymous]
    public async Task<List<ProcessBaseData>> GetProcessDatas(ProcessProviderCommand command)
    {
        var time = DateTime.Now;
        var data= await _grpcService.GetProcessDatas(command);

      

        return data;
    }

    ///// <summary>
    ///// 物流线写入
    ///// </summary>
    ///// <param name="write"></param>
    ///// <returns></returns>
    //[HttpPost]
    //[ApiDescriptionSettings(Name = "CvWrite")]
    //[AllowAnonymous]
    //public async Task CvWrite(CvPlcWrite write)
    //{
    //    // 不请求调度信息，从数据库获取
    //    var equipId = await _tagService.GetEquipIdByTagNum(write.Num.ToString());
    //    await _tagService.WriteTag(new Views.EquipTagView.Dto.EquipTagWriteDto
    //    {
    //        EquipId = equipId,
    //        Mode = 1,
    //        Num = write.Num.ToString(),
    //        ProtobufType = IotProtobufType.SIEMENS_S7.ToString(),
    //        Names="W_TASK,W_TARGET,W_COMMAND",
    //        Datas=$"{write.Task},{write.Dest},{write.Command}"

    //    });

    //}
    /// <summary>
    /// 物流线写入
    /// </summary>
    /// <param name="write"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "CvWrite")]
    [AllowAnonymous]
    public async Task CvWrite(CvPlcWrite write)
    {
        // 不请求调度信息，从数据库获取
        var equipId = await _tagService.GetEquipIdByTagNum(write.Num.ToString());
        await _tagService.WriteTag(new Views.EquipTagView.Dto.EquipTagWriteDto
        {
            EquipId = equipId,
            Mode = 1,
            Num = write.Num.ToString(),
            ProtobufType = IotProtobufType.SIEMENS_S7.ToString(),
            Names = "W_TASK,W_DEST,W_TRAY_TYPE,W_DONE",
            Datas = $"{write.Task},{write.Dest},{write.TrayType},1"

        });

    }

    /// <summary>
    /// 叠盘机写入
    /// </summary>
    /// <param name="write"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "StackWrite")]
    [AllowAnonymous]
    public async Task StackWrite(F29StackPlcWrite write)
    {
        // 不请求调度信息，从数据库获取
        var equipId = await _tagService.GetEquipIdByTagNum(write.Num);
        await _tagService.WriteTag(new Views.EquipTagView.Dto.EquipTagWriteDto
        {
            EquipId = equipId,
            Mode = 1,
            Num = write.Num,
            ProtobufType = IotProtobufType.SIEMENS_S7.ToString(),
            Names = "W_TIME",
            Datas = $"{write.StackOnTime}"

        });

    }

    /// <summary>
    /// 堆垛机写入
    /// </summary>
    /// <param name="write"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "ScWrite")]
    [AllowAnonymous]
    public async Task ScWrite(ScPlcWrite write)
    {
        var equipId = await _equipService.GetIdByNum(write.Num.ToString());
        var data = new Views.EquipTagView.Dto.EquipTagWriteDto
        {
            EquipId = equipId,
            Mode = 1,
            Num = write.Num,
            ProtobufType = IotProtobufType.SIEMENS_S7.ToString()
        };
        if (write.Fork == 1)
        {
            data.Names = "W_Z,W_X,W_Y,W_FRONT_TASK,W_CHOOSE_FORK,W_COMMAND";
            data.Datas = $"{write.Z},{write.X},{write.Y},{write.Task},{write.Fork},{write.Command}";

        }
        else if(write.Fork == 2)
        {
            data.Names = "W_Z,W_X,W_Y,W_BACK_TASK,W_CHOOSE_FORK,W_COMMAND";
            data.Datas = $"{write.Z},{write.X},{write.Y},{write.Task},{write.Fork},{write.Command}";
        }
        else if(write.Fork == 3)
        {
            data.Names = "W_Z,W_X,W_Y,W_FRONT_TASK,W_BACK_TASK,W_CHOOSE_FORK,W_COMMAND";
            data.Datas = $"{write.Z},{write.X},{write.Y},{write.Task},{write.Task2},{write.Fork},{write.Command}";
        }
        await _tagService.WriteTag(data);
    }


    /// <summary>
    /// 29工厂堆垛机写入
    /// </summary>
    /// <param name="write"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "ScWrite29")]
    [AllowAnonymous]
    public async Task ScWrite29(F29ScPlcWrite write)
    {

        if (write.Reset == 0 && write.FireLocation == 0)
        {


            var job = write.Adapt<F29EnterJob>();

            job.EquipNum = write.Num;

            job.JobID = Guid.NewGuid().ToString();
            // 以任务的方式去执行
            await _grpcService.AddProcessJob(new ProcessJobCommand
            {
                Job = job,
                ProviderType = ProcessProviderType.EnterJob
            });
            return;
        }



        var equipId = await _equipService.GetIdByNum(write.Num);

        // 下面是直接写入plc
        var dto = new Views.EquipTagView.Dto.EquipTagWriteDto
        {
            EquipId = equipId,
            Mode = 2,
            Num = write.Num,
            ProtobufType = IotProtobufType.SIEMENS_S7.ToString()
        };
        if (write.Reset == 1)
        {
            dto.Names = "W_RESET,W_SEND";
            dto.Datas = "1,1";
        }
        else if (write.FireLocation > 0)
        {
            dto.Names = "W_FIRE_LOCATION,W_SEND";
            dto.Datas = $"{write.FireLocation},1";
        }
        await _tagService.WriteTag(dto);
        return;
       // 下面是直接写入plc
        //var data = new Views.EquipTagView.Dto.EquipTagWriteDto
        //{
        //    EquipId = equipId,
        //    Mode = 2,
        //    Num = write.Num,
        //    ProtobufType = IotProtobufType.SIEMENS_S7.ToString()
        //};
        //if (write.UsePoke == 1)
        //{
        //    data.Names = "W_FROM_X,W_FROM_Y,W_FROM_Z,W_TO_X,W_TO_Y,W_TO_Z,W_TRAY";

        //    data.Datas = $"{write.FromX},{write.FromY},{write.FromZ},{write.ToX},{write.ToY},{write.ToZ},{write.Tray}";

            

        //}
        //else if (write.UsePoke == 2)
        //{
        //    data.Names = "W_FROM_X2,W_FROM_Y2,W_FROM_Z2,W_TO_X2,W_TO_Y2,W_TO_Z2,W_RIGHT_TRAY";

        //    data.Datas = $"{write.FromX2},{write.FromY2},{write.FromZ2},{write.ToX2},{write.ToY2},{write.ToZ2},{write.RightTray}";
        //}
        //else if (write.UsePoke == 3 || write.UsePoke==4)
        //{
        //    data.Names = "W_FROM_X,W_FROM_Y,W_FROM_Z,W_TO_X,W_TO_Y,W_TO_Z,W_TRAY,W_FROM_X2,W_FROM_Y2,W_FROM_Z2,W_TO_X2,W_TO_Y2,W_TO_Z2,W_RIGHT_TRAY";

        //    data.Datas = $"{write.FromX},{write.FromY},{write.FromZ},{write.ToX},{write.ToY},{write.ToZ},{write.Tray},{write.FromX2},{write.FromY2},{write.FromZ2},{write.ToX2},{write.ToY2},{write.ToZ2},{write.RightTray}";
        //}

       

        //if (write.Tray2.IsNotNullOrEmpty())
        //{
        //    data.Names += ",W_TRAY2";
        //    data.Datas += $",{write.Tray2}";
        //}
        //if (write.RightTray2.IsNotNullOrEmpty())
        //{
        //    data.Names += ",W_RIGHT_TRAY2";
        //    data.Datas += $",{write.RightTray2}";
        //}
        //data.Names += ",W_POKE_USE,W_SEND";
        //data.Datas += $",{write.UsePoke},1";
        //await _tagService.WriteTag(data);

       
    }

    /// <summary>
    /// 移除入库任务
    /// </summary>
    /// <param name="job"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "RemoveEnterJob")]
    [AllowAnonymous]
    public async Task RemoveEnterJob(F29EnterJob job)
    {
      var result= await _grpcService.RemoveProcessJob(new ProcessJobCommand
        {
            Job = job,
            ProviderType = ProcessProviderType.EnterJob
        });

        if (result.IsNotNullOrEmpty())
        {
            throw Oops.Oh(result);
        }
    }

    /// <summary>
    /// 移除出库任务
    /// </summary>
    /// <param name="job"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "RemoveOutJob")]
    [AllowAnonymous]
    public async Task RemoveOutJob(F29OutJob job)
    {
        var result = await _grpcService.RemoveProcessJob(new ProcessJobCommand
        {
            Job = job,
            ProviderType = ProcessProviderType.OutJob
        });

        if (result.IsNotNullOrEmpty())
        {
            throw Oops.Oh(result);
        }
    }
    /// <summary>
    /// 任务完成
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name ="CompleteJob")]
    [AllowAnonymous]
    public async Task CompleteJob(FmsJobCompleteRequest request)
    {
       var result= await _grpcService.CompleteJob(request);
        if (result.IsNotNullOrEmpty())
        {
            throw Oops.Oh(result);
        }
    }
    /// <summary>
    /// 移除移库任务
    /// </summary>
    /// <param name="job"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "RemoveMoveJob")]
    [AllowAnonymous]
    public async Task RemoveMoveJob(F29MoveJob job)
    {
        var result = await _grpcService.RemoveProcessJob(new ProcessJobCommand
        {
            Job = job,
            ProviderType = ProcessProviderType.MoveJob
        });

        if (result.IsNotNullOrEmpty())
        {
            throw Oops.Oh(result);
        }
    }

    /// <summary>
    /// 移除火警任务
    /// </summary>
    /// <param name="job"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "RemoveFireJob")]
    [AllowAnonymous]
    public async Task RemoveFireJob(F29MoveJob job)
    {
        var result = await _grpcService.RemoveProcessJob(new ProcessJobCommand
        {
            Job = job,
            ProviderType = ProcessProviderType.FireJob
        });

        if (result.IsNotNullOrEmpty())
        {
            throw Oops.Oh(result);
        }
    }

    /// <summary>
    /// 移除充放电任务
    /// </summary>
    /// <param name="job"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "RemoveFmtJob")]
    [AllowAnonymous]
    public async Task RemoveFmtJob(F29FmtJob job)
    {
        var result = await _grpcService.RemoveProcessJob(new ProcessJobCommand
        {
            Job = job,
            ProviderType = ProcessProviderType.FmtJob
        });

        if (result.IsNotNullOrEmpty())
        {
            throw Oops.Oh(result);
        }
    }



    /// <summary>
    /// 获取托盘信息--待优化
    /// </summary>
    /// <param name="input">托盘号</param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "GetTrayInfo")]
    [AllowAnonymous]
    public async Task<List<FmsTrayInfoResponse>> GetTrayInfo([FromQuery] string input)
   {
        //sql待优化
       var sql = $@"SELECT RCT.TRAY_NO   TrayNo1,
       RCT.TIME_STR  timeStr1,
       TTI1.IS_NG    isNg1,
       M1.MODEL_CODE modelCode1,
       ci1.LOT_NO    lotNo1,
       ci1.LINE_NO   lineNo1,
       R1.ROUTE_CODE routeCode1,
       s1.STEP_NAME  stepName1,
       cc1.cellCount cellCount1,
       tc1.ngCount   ngCount1,
       RCT.TRAY_NO2  TrayNo2,
       RCT.TIME_STR2 timeStr2,
       TTI2.IS_NG    isNg2,
       M2.MODEL_CODE modelCode2,
       ci2.LOT_NO    lotNo2,
       ci2.LINE_NO   lineNo2,
       R2.ROUTE_CODE routeCode2,
       s2.STEP_NAME  stepName2,
       cc2.cellCount cellCount2,
       tc2.ngCount   ngCount2
FROM REC_CONVEYOR_TASK RCT
         LEFT JOIN TH_TASK_NO TTN ON RCT.TASK_NUM_ID = TTN.ID
         left join TH_TRAY_INFO TTI1 ON TTI1.TRAY_NO = RCT.TRAY_NO
         left join TH_PRODUCT_MODEL M1 on TTI1.PRODUCT_MODEL_ID = M1.ID
         left join TH_ROUTE R1 on R1.PRODUCT_MODEL_ID = TTI1.PRODUCT_MODEL_ID
         left join TH_CELL_LOT cl1 on cl1.TRAY_NO = RCT.TRAY_NO and cl1.TIME_STR = RCT.TIME_STR
         left join (select c1.tray_no, c1.TIME_STR, count(c1.CELL_NO) as cellCount
                    from TH_CELL_LOT c1
                    group by c1.TRAY_NO, c1.TIME_STR) cc1 on cc1.TRAY_NO = RCT.TRAY_NO and cc1.TIME_STR = RCT.TIME_STR
         left join (select tcr1.tray_no, tcr1.time_str, count(tcr1.CELL_NO) as ngCount
                    from REC_TRAY_CELL_REF tcr1
                    where tcr1.IS_NG = 1
                      and tcr1.status = 1
                      and tcr1.IS_LAST = 1
                      and tcr1.IS_DEL = 0
                    group by tcr1.tray_no, tcr1.time_str) tc1
                   on tc1.TRAY_NO = RCT.TRAY_NO and tc1.TIME_STR = RCT.TIME_STR
         left join TH_ROUTE_STEP_REF rsr1 on rsr1.id = cl1.CURRENT_ROUTE_STEP_ID
         left join TH_STEP s1 on s1.ID = rsr1.STEP_ID
         left join REC_CELL_INFO ci1 on ci1.CELL_NO = cl1.CELL_NO
         left join TH_TRAY_INFO TTI2 ON TTI2.TRAY_NO = RCT.TRAY_NO2
         left join TH_PRODUCT_MODEL M2 on TTI2.PRODUCT_MODEL_ID = M2.ID
         left join TH_ROUTE R2 on R2.PRODUCT_MODEL_ID = TTI2.PRODUCT_MODEL_ID
         left join TH_CELL_LOT cl2 on cl2.TRAY_NO = RCT.TRAY_NO and cl2.TIME_STR = RCT.TIME_STR2
         left join (select c2.tray_no, c2.TIME_STR, count(c2.CELL_NO) as cellCount
                    from TH_CELL_LOT c2
                    group by c2.TRAY_NO, c2.TIME_STR) cc2 on cc2.TRAY_NO = RCT.TRAY_NO2 and cc2.TIME_STR = RCT.TIME_STR2
         left join (select tcr2.tray_no, tcr2.time_str, count(tcr2.CELL_NO) as ngCount
                    from REC_TRAY_CELL_REF tcr2
                    where tcr2.IS_NG = 1
                      and tcr2.status = 1
                      and tcr2.IS_LAST = 1
                      and tcr2.IS_DEL = 0
                    group by tcr2.tray_no, tcr2.time_str) tc2
                   on tc2.TRAY_NO = RCT.TRAY_NO2 and tc2.TIME_STR = RCT.TIME_STR2
         left join TH_ROUTE_STEP_REF rsr2 on rsr2.id = cl2.CURRENT_ROUTE_STEP_ID
         left join TH_STEP s2 on s2.ID = rsr2.STEP_ID
         left join REC_CELL_INFO ci2 on ci2.CELL_NO = cl2.CELL_NO
WHERE TTN.TASK_NO = '{input}'
  and R1.IS_MAIN = 1
  and R1.STATUS = 1
  and ROWNUM = 1";



        var datas = await _sqlSugarClient.Ado.SqlQueryAsync<FmsTrayInfoResponseTest>(sql);

        List<FmsTrayInfoResponse> fmsTrayInfoResponse =new List<FmsTrayInfoResponse>();

        if (datas != null && datas.Count>0)
        {
            var res = datas.First();
            if(res.TrayNo1 != null)
            {
                fmsTrayInfoResponse.Add(new FmsTrayInfoResponse()
                {
                    CellCount = res.CellCount1,
                    IsNG = res.IsNg1,
                    LotNo = res.LotNo1 == null ? "" : res.LotNo1,
                    ModelCode = res.ModelCode1 == null ? "" : res.ModelCode1,
                    NgCount = res.NgCount1,
                    RouteCode = res.RouteCode1 == null ? "" : res.RouteCode1,
                    StepName = res.StepName1 == null ? "" : res.StepName1,
                    TimeStr = res.TimeStr1 == null ? "" : res.TimeStr1,
                    TrayNo = res.TrayNo1 == null ? "" : res.TrayNo1,
                });
            }
            if (res.TrayNo2 != null)
            {
                fmsTrayInfoResponse.Add(new FmsTrayInfoResponse()
                {
                    CellCount = res.CellCount2,
                    IsNG = res.IsNg2,
                    LotNo = res.LotNo2 == null ? "" : res.LotNo2,
                    ModelCode = res.ModelCode2 == null ? "" : res.ModelCode2,
                    NgCount = res.NgCount2,
                    RouteCode = res.RouteCode2 == null ? "" : res.RouteCode2,
                    StepName = res.StepName2 == null ? "" : res.StepName2,
                    TimeStr = res.TimeStr2 == null ? "" : res.TimeStr2,
                    TrayNo =  res.TrayNo2 == null?"": res.TrayNo2,
                });
            }

            return fmsTrayInfoResponse;
        }


        return null;
    }
//    /// <summary>
//    /// 获取托盘信息
//    /// </summary>
//    /// <returns></returns>
//    public async Task<TrayInformationDto> GetTrayInformations(string input)
//    {
//        var sql = $@"
//            SELECT * FROM 
//(SELECT lot.TRAY_NO, lot.TIME_STR, lot.LOT_NO,m.MODEL_CODE,r.ROUTE_CODE,s.STEP_ALIAS,t.IS_NG
//FROM TH_CELL_LOT lot
//LEFT JOIN TH_TRAY_INFO t ON lot.TRAY_NO  = t.TRAY_NO 
//LEFT JOIN TH_PRODUCT_MODEL m ON lot.PRODUCT_MODEL_ID  = m.ID 
//LEFT JOIN TH_ROUTE r ON lot.ROUTE_ID = r.ID 
//LEFT JOIN TH_ROUTE_STEP_REF s ON s.ID  = lot.CURRENT_ROUTE_STEP_ID 
//WHERE lot.TRAY_NO  = '{input}'
//AND lot.TIME_STR  = (SELECT TIME_STR
//        FROM (SELECT TIME_STR
//              FROM REC_TRAY_BIND
//              WHERE IS_ACTIVE = 1 and tray_no = '{input}'
//              ORDER BY CREATE_TIME DESC)
//        WHERE ROWNUM = 1)
//AND t.IS_DEL  = 0
//AND lot.IS_DEL  = 0)
//WHERE ROWNUM = 1";


//        var datas =await  _sqlSugarClient.Ado.SqlQueryAsync<TrayInformationDto>(sql);

//        if (datas != null)
//        {
            
//            return datas.First();
//        }
//        else
//        {
//            return null;
//        }

//    }

    /// <summary>
    /// 获取堆垛机信息
    /// </summary>
    /// <param name="input">托盘号</param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "GetFmsScInfo")]
    [AllowAnonymous]
    public async Task<FmsScReponse> GetFmsScInfo([FromQuery] string input)
    {
        var sql = $@"
            WITH T AS
(SELECT STACKER_ID,LOC,LOC_CODE,ALLOW_IN,STATUS FROM TH_WH_CHARGE  WHERE IS_DEL=0
UNION ALL
SELECT STACKER_ID,LOC,LOC_CODE,ALLOW_IN,STATUS  FROM TH_WH_ROOM_TEMP WHERE IS_DEL=0
UNION ALL
SELECT STACKER_ID,LOC,LOC_CODE,ALLOW_IN,STATUS  FROM TH_WH_HIGH_TEMP WHERE IS_DEL=0)
SELECT  
TS.STACKER_CODE,
COUNT(CASE WHEN T.STATUS = 2 THEN 1 END) loadNum,
COUNT(CASE WHEN T.STATUS = 0 AND ALLOW_IN = 1 THEN 1 END) availableNum
FROM TH_STACKER TS
LEFT JOIN T ON TS.ID = T.STACKER_ID
WHERE TS.IS_DEL = 0 AND TS.STACKER_CODE = '{input}'
GROUP BY TS.STACKER_CODE";


        var datas = await _sqlSugarClient.Ado.SqlQueryAsync<FmsScReponse>(sql);

        if (datas != null&& datas.Count>0)
        {
            return datas.First();
        }
        else
        {
            return null;
        }
    }
   

    /// <summary>
    /// 获取所有设备报警代码和文本
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "GetEquipIssusCode")]
    [AllowAnonymous]
    public async Task<List<FmsEquECodeResponse>> GetEquipIssusCode()
    {
        var sql = @"select eic.ISSUE_CODE         issueCode,
                           eic.ISSUE_NAME         issueName,
                           et.EQUIPMENT_TYPE_CODE equipmentTypeCode,
                           et.EQUIPMENT_TYPE_NAME equipmentTypeName
                    from TH_EQUIPMENT_ISSUE_CODE eic
                           left join TH_EQUIPMENT_TYPE et on eic.EQUIPMENT_TYPE_ID = et.ID"
;
        var datas = await _sqlSugarClient.Ado.SqlQueryAsync<FmsEquECodeResponse>(sql);

            return datas;

    }


    // 写入扫码枪







    #endregion



}


